import os
import sys
import time
import subprocess

import requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import json
from config.global_settings import DEFAULT_WAIT, \
    YFYS_DOWNLOAD_PATH, ENVIRON_PATH, CHROME_PATH, \
    gx_username, gx_password, cj_username, cj_password, API_UPLOAD, UPLOAD_PATH, API_CONFIRM_URL, API_SYNC_URL, \
    API_ADD_URL, API_CLEAR_URL, FPDK_URL, jsp_password
from selenium.webdriver.common.by import By
from pywinauto import keyboard

from data_util.my_log import logger


class TaxDeduction():
    def __init__(self, fpdk_url,  download_path):
        """
        初始化
        :param url: 八局url
        :param download_path: 附件/发票下载路径
        :param body: 填报信息
        """
        self.xh = None
        self.url = fpdk_url
        self.filename = None
        self.download_path = download_path
        subprocess.Popen(
            rf'"{environ_list.get("chrome_path")}" --flag-switches-begin --flag-switches-end --remote-debugging-port=80 --user-data-dir="{environ_list.get("default_path")}"')
        options = Options()
        # options = webdriver.ChromeOptions()
        # 启动的浏览器地址
        # options.debugger_address = '127.0.0.1:80'
        options.debugger_address = '127.0.0.1:80'
        options.binary_location = environ_list.get("chrome_path")  # 手动指定使用的浏览器位置
        # 将浏览器配置信息进行添加
        self.driver = webdriver.Chrome(options=options, executable_path=CHROME_PATH)
        self.driver.maximize_window()

    def fill_input(self, xpath, content, timeout=DEFAULT_WAIT):
        """
        填写网页表单
        :param xpath: xpath
        :param content: 填写内容
        :param timeout: 等待元素出现时间，若超时则报错
        :return:
        """
        element = WebDriverWait(driver=self.driver, timeout=timeout, poll_frequency=0.5).until(
            EC.presence_of_element_located((By.XPATH, xpath))
        )
        self.click_element(xpath, timeout=timeout)
        element.send_keys(content)

    def click_element(self, xpath, timeout=DEFAULT_WAIT, mode='internal'):
        """
        点击元素
        :param mode: 点击元素的模式
        :param xpath: xpath
        :param timeout: 等待元素出现时间，若超时则报错
        :return: None
        """
        element_located = WebDriverWait(driver=self.driver, timeout=timeout, poll_frequency=0.5).until(
            EC.presence_of_element_located((By.XPATH, xpath))
        )
        if mode == 'internal':
            element = WebDriverWait(driver=self.driver, timeout=timeout, poll_frequency=0.5).until(
                EC.element_to_be_clickable((By.XPATH, xpath))
            )
            element.click()
        elif mode == 'external':
            self.driver.execute_script("$(arguments[0]).click()", element_located)

    def find_elements(self, xpath, timeout=DEFAULT_WAIT):
        """
        通过xpath去寻找所有元素，返回多个元素对象
        :param xpath: xpath
        :param timeout: 等待元素出现时间，若超时则报错
        :return:
        """
        elements = WebDriverWait(driver=self.driver, timeout=timeout, poll_frequency=0.5).until(
            EC.presence_of_all_elements_located((By.XPATH, xpath))
        )
        return elements

    def find_element(self, xpath, timeout=DEFAULT_WAIT):
        """
        通过xpath寻找元素，并返回元素对象
        :param xpath: xpath
        :param timeout: 等待元素出现时间，若超时则报错
        :return:
        selenium等待presence_of_element_located
        页面元素等待处理。
        """
        element = WebDriverWait(driver=self.driver, timeout=timeout, poll_frequency=0.5).until(
            EC.presence_of_element_located((By.XPATH, xpath))
        )
        return element

    def find_element_by_xpath(xpath='', chromeBrowser=''):
        try:
            elem = chromeBrowser.find_element_by_xpath(xpath)
            return elem
        except Exception as e:
            print(e)
            logger.error("未找到xpath:" + xpath)
            return False

    def run(self):
        logger.info('确收审查填报开始...')
        # 清空文件夹
        # self.clear_file()
        #
        # # 将共享作业平台的待办已办置为初始状态
        # self.API_clear()
        #
        # 登录增值税发票综合服务平台(安徽)
        self.login()
        #
        # # 从共享平台爬取收入确认数据并调用接口给数智平台新增数据
        # self.getConfirmDataFromWebPage()
        #
        # # 登录数智财经管理平台
        # self.login_digital()
        #
        # # 确收审查-RPA状态同步
        # self.driver.refresh()
        # logger.info('等待人工复核...')
        # self.syncStatus()
        # logger.info('确收审查填报成功...')

    def clear_file(self):
        """
        root  # 当前目录路径
        dirs  # 当前路径下所有子目录
        files  # 当前路径下所有非目录子文件
        :return:
        """
        for root, dirs, files in os.walk(self.download_path):
            if not files:
                return
            for file in files:
                dir_path = os.path.join(self.download_path, file)
                os.remove(dir_path)

    def login(self):
        logger.info('登录增值税发票综合服务平台(安徽)')
        self.driver.get(self.url)
        # 你的连接不是私密连接

        try:
            self.click_element('//button[@id="details-button"]', mode='internal')
            time.sleep(0.5)
            self.click_element('//a[@id="proceed-link"]', mode='internal')
        except:
            ...

        # 可能弹出升级内容说明
        try:
            self.click_element('//a[@id="okButton"]', mode='internal')
        except:
            ...

        # 输入用户名和密码
        time.sleep(1)
        # self.fill_input('//input[@id="password1"]', jsp_password)
        # find_element_by_xpath('//*[@id="username"]', chromeBrowser).send_keys(username)
        ele = self.find_element('//input[@id="password1"]')
        # ActionChains(chromeBrowser).click(ele).send_keys('12345678').perform()
        time.sleep(1)
        self.click_element('//button[@id="submit"]', mode='internal')
        time.sleep(0.7)
        logger.info('登录增值税发票综合服务平台(安徽)')

    def getConfirmDataFromWebPage(self):
        """
        从网页爬取数据
        :return:
        """
        logger.info('从共享作业平台爬取收入确认待办数据开始')
        self.click_element('//a[contains(@href,"revenueRec")]', mode='internal')
        self.click_element('//div[@class="ant-list-item-meta"]', mode='internal')
        data = []
        confirm_review = {}
        # 获取流程编号
        flow_number = self.find_element("//input[@id='flowNumber']").get_attribute('value')
        confirm_review['flowNumber'] = flow_number
        # 获取采购编号
        purchase_number = self.find_element("//input[@id='purchaseNumber']").get_attribute('value')
        confirm_review['purchaseNumber'] = purchase_number
        # 确收金额
        receive_money = self.find_element("//input[@id='receiveMoney']").get_attribute('value')
        confirm_review['receiveMoney'] = receive_money
        time.sleep(1)
        # 下载销售订单
        self.click_element('//button[@id="purchaseUrl"]', mode='internal')
        time.sleep(1)
        # 获得当前所有打开的窗口的句柄
        all_handles = self.driver.window_handles
        oa_handle0 = all_handles[0]
        oa_handle1 = all_handles[1]
        # 切换待办页面
        self.driver.switch_to.window(oa_handle1)
        keyboard.send_keys("^s")
        time.sleep(3)
        keyboard.send_keys("销售订单.pdf")
        time.sleep(1)
        keyboard.send_keys('{ENTER}')
        time.sleep(0.5)
        self.driver.close()
        time.sleep(0.2)
        self.driver.switch_to.window(oa_handle0)

        confirm_review['purchaseOrigin'] = '销售订单.pdf'
        # 下载发货单
        self.click_element('//button[@id="sendUrl"]', mode='internal')
        # 获得当前所有打开的窗口的句柄
        time.sleep(1)
        all_handles = self.driver.window_handles
        oa_handle0 = all_handles[0]
        oa_handle1 = all_handles[1]
        # 切换待办页面
        self.driver.switch_to.window(oa_handle1)
        keyboard.send_keys("^s")
        time.sleep(3)
        keyboard.send_keys("发货单.pdf")
        time.sleep(1)
        keyboard.send_keys('{ENTER}')
        time.sleep(0.5)
        self.driver.close()
        time.sleep(0.2)
        self.driver.switch_to.window(oa_handle0)
        confirm_review['sendOrigin'] = '发货单.pdf'

        # 上传文件
        # 上传销售订单
        xsdd = self.API_upload(confirm_review['purchaseOrigin'])
        logger.info('上传销售订单结束')
        confirm_review['purchaseOrigin'] = xsdd

        # 上传发货单
        fhd = self.API_upload(confirm_review['sendOrigin'])
        logger.info('上传发货单结束')
        confirm_review['sendOrigin'] = fhd



        data.append(confirm_review)

        self.API_add(data[0])
        self.filename = os.path.join(self.download_path, 'confirmReview.json')
        with open(self.filename, 'w') as file_obj:
            file_obj.write(json.dumps(data, ensure_ascii=False))
        logger.info('从共享作业平台爬取收入确认待办数据成功')

    def login_digital(self):
        logger.info('登录数智财经管理平台开始')
        self.driver.get(self.ARAP_URL)
        # 输入用户名和密码
        self.fill_input('//input[@id="username"]', cj_username)
        self.fill_input('//input[@id="password"]', cj_password)
        self.click_element('//button[@class="ant-btn ant-btn-primary"]', mode='internal')
        # 点击确收审查超链接
        time.sleep(1)
        self.click_element('//a[contains(@href,"baseManage")]', mode='internal')
        logger.info('登录数智财经管理平台成功')

    def get_list(self):
        """
        调用待同步数据接口
        :return:
        """
        try:
            res_back = requests.get(API_CONFIRM_URL)
            if res_back.status_code == 200:
                result = res_back.json().get('data')[0]
                # print(result)
                return result
            else:
                return ''
        except:
            # logger.error('接口调用失败')
            ...

    def API_sync_status(self):
        """
        调用RPA状态同步接口
        :return:
        """
        try:
            params = {
                "rpaStatus": 2
            }
            res_back = requests.get(API_SYNC_URL, params=params)
            # print(res_back.json())

        except:
            # logger.error('接口调用失败')
            ...

    def syncStatus(self):
        data = self.get_list()

        if not data:
            # print('轮询')
            time.sleep(4)
            self.syncStatus()
        else:
            logger.info('人工复核成功...')
            self.examConfirm(data)
            # print('不用轮询接着走')

    def getDataFromJsonFile(self):
        """
        从json文件读取数据
        :return:
        """
        self.filename = os.path.join(self.download_path, 'invoiceInfo.json')
        with open(self.filename) as f:
            company_list = json.load(f)
        return company_list

    def get_html_title(self):
        title_xpath = 'html/head/title'
        ele = self.find_element(title_xpath)
        title = ele.get_attribute("textContent")
        return title

    def API_add(self, data):
        try:
            headers = {
                "Content-Type": "application/json"
            }
            # cipher = RSACipher()
            # sign = cipher.encrypt_with_public_key(str(time.time())).decode()
            # data['time_key'] = sign
            requests.post(API_ADD_URL, data=json.dumps(data), headers=headers)
            # if res.status_code == '200':
            # logger.error('新增结果请求成功')
            # else:
            #     logger.error(f'新增结果回传失败,状态码:{res.status_code}，data:{data}')
        except:
            logger.error('新增结果回传接口请求失败')

    def API_upload(self, file_name):
        files = {}
        file_path = ''
        try:
            file_path = os.path.join(UPLOAD_PATH, file_name)
            files = {'file': open(file_path, 'rb')}
            res = requests.post(API_UPLOAD, files=files)
            if res.status_code == 200:
                return res.json().get('data')
            else:
                logger.error(f'上传文件失败,状态码:{res.status_code}，data:{res.json()}')
        except:
            logger.error('上传文件请求失败')

    def examConfirm(self, data):
        logger.info('RPA状态同步开始')
        # 将共享作业平台的待办已办置为初始状态
        # self.API_clear()
        # 登录共享作业平台
        self.login()
        time.sleep(0.5)
        self.click_element('//a[contains(@href,"revenueRec")]', mode='internal')
        time.sleep(0.5)
        self.click_element('//div[@class="ant-list-item-meta"]', mode='internal')
        time.sleep(1)
        # print("compareMessage"+data.get('compareMessage'))
        # if data.get('compareMessage'):
        #     self.fill_input('//input[@id = "remark"]', data.get('compareMessage'))
        # else:
        self.fill_input('//input[@id = "remark"]', data.get('compareMessage'))

        time.sleep(1)
        # 点击通过或者不通过按钮
        # 通过
        if 2 == data.get('auditStatus'):
            self.click_element('//button[@class = "ant-btn ant-btn-primary"]', mode='internal')
        elif 3 == data.get('auditStatus'):
            self.click_element('//span[text() = "不通过"]/..', mode='internal')

        # 调用状态同步接口
        self.API_sync_status()
        logger.info('RPA状态同步成功')

    def API_clear(self):
        """
        清除应收，还原待办接口
        :return:
        """
        try:
            res_back = requests.get(API_CLEAR_URL)
            # print(res_back.json())
        except:
            logger.info('等待人工复核...')


if __name__ == '__main__':
    filename = os.path.join(ENVIRON_PATH)
    with open(filename) as f:
        environ_list = json.load(f)
        # print(environ_list)

    if not os.path.exists(environ_list.get("download_path")):
        os.mkdir(environ_list.get("download_path"))
    DownLoadPath = environ_list.get("download_path")
    if not os.path.exists(DownLoadPath):
        os.mkdir(DownLoadPath)


    taxDeduction = TaxDeduction(fpdk_url=FPDK_URL, download_path=DownLoadPath)
    taxDeduction.run()
